home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / QuakeTools / src / libqdisplay / clippoly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  3.1 KB  |  129 lines

  1. #define    LIBQDISPLAY_CORE
  2. #include "../include/libqdisplay.h"
  3.  
  4. /*
  5.  * CLIPPOLY.c - LOTS OF WORK TO DO :) 
  6.  */
  7.  
  8. static point_3d clipPoints[16], *clipList1[40], *clipList2[40];
  9.  
  10. #define X p[0]
  11. #define Y p[1]
  12. #define Z p[2]
  13.  
  14. static void intersect(point_3d * out, point_3d * a, point_3d * b, float where)
  15. {
  16.   // intersection occurs 'where' % along the line from a to b
  17.   out->X = a->X + (b->X - a->X) * where;
  18.   out->Y = a->Y + (b->Y - a->Y) * where;
  19.   out->Z = a->Z + (b->Z - a->Z) * where;
  20.  
  21.   transform_rotated_point(out);
  22. }
  23.  
  24. // compute 'where' for various clip planes
  25. static float left_loc(point_3d * a, point_3d * b)
  26. {
  27.   return -(a->Z + a->X * clipScaleX) / ((b->X - a->X) * clipScaleX + b->Z - a->Z);
  28. }
  29.  
  30. static float right_loc(point_3d * a, point_3d * b)
  31. {
  32.   return (a->Z - a->X * clipScaleX) / ((b->X - a->X) * clipScaleX - b->Z + a->Z);
  33. }
  34.  
  35. static float top_loc(point_3d * a, point_3d * b)
  36. {
  37.   return (a->Z - a->Y * clipScaleY) / ((b->Y - a->Y) * clipScaleY - b->Z + a->Z);
  38. }
  39.  
  40. static float bottom_loc(point_3d * a, point_3d * b)
  41. {
  42.   return -(a->Z + a->Y * clipScaleY) / ((b->Y - a->Y) * clipScaleY + b->Z - a->Z);
  43. }
  44.  
  45. // clip the polygon to each of the view frustrum planes
  46. int clip_poly(int n, point_3d ** vl, int codes_or, point_3d *** out_vl)
  47. {
  48.   int i, j, k, p = 0;                                   // p = index into temporary point pool
  49.  
  50.   point_3d **cur;
  51.  
  52.   if (codes_or & CC_OFF_LEFT) {
  53.     cur = clipList1;
  54.     k = 0;
  55.     j = n - 1;
  56.     for (i = 0; i < n; ++i) {
  57.       // process edge from j..i
  58.       // if j is inside, add it
  59.       if (!(vl[j]->ccodes & CC_OFF_LEFT))
  60.     cur[k++] = vl[j];
  61.       // if it crosses, add the intersection point
  62.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_LEFT) {
  63.     intersect(&clipPoints[p], vl[i], vl[j], left_loc(vl[i], vl[j]));
  64.     cur[k++] = &clipPoints[p++];
  65.       }
  66.       j = i;
  67.     }
  68.     // move output list to be input
  69.     n = k;
  70.     vl = cur;
  71.   }
  72.  
  73.   if (codes_or & CC_OFF_RIGHT) {
  74.     cur = (vl == clipList1) ? clipList2 : clipList1;
  75.     k = 0;
  76.     j = n - 1;
  77.     for (i = 0; i < n; ++i) {
  78.       if (!(vl[j]->ccodes & CC_OFF_RIGHT))
  79.     cur[k++] = vl[j];
  80.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_RIGHT) {
  81.     intersect(&clipPoints[p], vl[i], vl[j], right_loc(vl[i], vl[j]));
  82.     cur[k++] = &clipPoints[p++];
  83.       }
  84.       j = i;
  85.     }
  86.     n = k;
  87.     vl = cur;
  88.   }
  89.   if (codes_or & CC_OFF_TOP) {
  90.     cur = (vl == clipList1) ? clipList2 : clipList1;
  91.     k = 0;
  92.     j = n - 1;
  93.     for (i = 0; i < n; ++i) {
  94.       if (!(vl[j]->ccodes & CC_OFF_TOP))
  95.     cur[k++] = vl[j];
  96.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_TOP) {
  97.     intersect(&clipPoints[p], vl[i], vl[j], top_loc(vl[i], vl[j]));
  98.     cur[k++] = &clipPoints[p++];
  99.       }
  100.       j = i;
  101.     }
  102.     n = k;
  103.     vl = cur;
  104.   }
  105.   if (codes_or & CC_OFF_BOT) {
  106.     cur = (vl == clipList1) ? clipList2 : clipList1;
  107.     k = 0;
  108.     j = n - 1;
  109.     for (i = 0; i < n; ++i) {
  110.       if (!(vl[j]->ccodes & CC_OFF_BOT))
  111.     cur[k++] = vl[j];
  112.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_BOT) {
  113.     intersect(&clipPoints[p], vl[i], vl[j], bottom_loc(vl[i], vl[j]));
  114.     cur[k++] = &clipPoints[p++];
  115.       }
  116.       j = i;
  117.     }
  118.     n = k;
  119.     vl = cur;
  120.   }
  121.  
  122.   for (i = 0; i < n; ++i)
  123.     if (vl[i]->ccodes & CC_BEHIND)
  124.       return 0;
  125.  
  126.   *out_vl = vl;
  127.   return n;
  128. }
  129.